package com.gcsoftware.web.controller.company;

import com.alibaba.fastjson.JSONObject;
import com.gcsoftware.authentications.beans.UserInfo;
import com.gcsoftware.authentications.helper.ShiroUtils;
import com.gcsoftware.utils.MapUtils;
import com.gcsoftware.utils.SysConst;
import com.gcsoftware.utils.WsSoapUtils;
import com.gcsoftware.utils.log.InvokeLog;
import com.gcsoftware.utils.log.LogUtils;
import com.gcsoftware.web.beans.*;
import com.gcsoftware.web.beans.request.GetAppsReq;
import com.gcsoftware.web.beans.request.GetInterfReq;
import com.gcsoftware.web.service.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by qs on 2018/3/26.
 */
@Controller
@RequestMapping("/enroll")
public class EnrollAppController {
    @Autowired
    private T_GW_APPS_SERVICE service;

    @Autowired
    private T_COM_SYS_DICT_SERVICE dictService;

    @Autowired
    private T_GW_VERIFY_SERVICE verifyService;

    @Autowired
    private T_GW_CHANGES_SERVICE changeService;

    @Autowired
    private T_GW_INTERF_SERVICE interfService;

    @RequestMapping("/apps")
    public String enrollApps(Model model) {
        model.addAttribute("appTypes" , dictService.queryForList(SysConst.DICT_GRP_APP_TYPES));
        model.addAttribute("appStatus" , dictService.queryForList(SysConst.DICT_GRP_APP_STATUS));
        return "enrolls/apps";
    }

    @RequestMapping(value = "/app-list" , method = RequestMethod.POST)
    @ResponseBody
    public List<T_GW_APPS> queryForList(@RequestParam(value = "c_APP_NAME" , required = false) String c_APP_NAME,
                                        @RequestParam(value = "c_APP_STATUS" , required = false) String c_APP_STATUS) {
        UserInfo userInfo  = ShiroUtils.getSessionAttribute("user");
//        userInfo
        return service.queryForList("".equals(c_APP_NAME)?null: c_APP_NAME,"".equals(c_APP_STATUS)?null: c_APP_STATUS,userInfo.getCompanyId());
    }

    @ResponseBody
    @RequestMapping(value = "/app/{c_APP_ID}/ips" , method = RequestMethod.POST)
    public List<T_GW_APP_IPS> queryIpListForAPP(@PathVariable(value = "c_APP_ID") String c_APP_ID) {
        return service.queryForIpList(c_APP_ID);
    }

    @ResponseBody
    @RequestMapping(value = "/app-save" , method = RequestMethod.POST)
    @InvokeLog(name = "app Save" , description = "新增应用信息" , logType = LogUtils.LOG_TYPE_OPERATE)
    public MapUtils appSave(@RequestBody String param){
        GetAppsReq appReq = JSONObject.parseObject(param , GetAppsReq.class); //string转json
        UserInfo userInfo  = ShiroUtils.getSessionAttribute("user");
        appReq.setC_COMPANY_ID(userInfo.getCompanyId());
        if(StringUtils.isBlank(appReq.getC_APP_ID())) {
            return service.appInsert(appReq);
        } else {
            return service.updateApp(appReq);
        }
    }

    @ResponseBody
    @RequestMapping(value = "/app-change" , method = RequestMethod.POST)
    @Transactional
    public MapUtils appChange(@RequestBody String param){
        String verifyId = verifyService.getVerifyId();
        GetAppsReq appReq = JSONObject.parseObject(param , GetAppsReq.class); //string转json
        //查询之前到应用信息，并与当前的信息比较，不同的部分写入change表
        T_GW_APPS apps = service.getById(appReq.getC_APP_ID());

        UserInfo userInfo = ShiroUtils.getSessionAttribute("user");

        if (null != apps) {
            List<T_GW_CHANGES> changeList = getDiffrentFromApps(verifyId,userInfo.getUserId(),apps,appReq);


            List<T_GW_APP_IPS> ips = service.queryForIpList(apps.getC_APP_ID());

            changeList.addAll(getDiffrentFromIps(verifyId,userInfo.getUserId(),ips,appReq.getIps()));


            if (CollectionUtils.isNotEmpty(changeList)) {
                verifyService.updateVerifyToUnable(appReq.getC_APP_ID(),null,SysConst.VERIFY_TYPE_APP_CHANGED);
                if (1 ==verifyService.insertVerify(userInfo.getUserId(),verifyId,SysConst.VERIFY_TYPE_APP_CHANGED,appReq.getC_APP_ID(),null,null,appReq.getC_APP_NAME())) {
                    //batch insert to change
                    return 1 == changeService.batchInsert(changeList) ? MapUtils.ok() : MapUtils.error("变更失败");
                } else {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                }

            }
        }
        return MapUtils.error("变更失败");
    }

    private List<T_GW_CHANGES> getDiffrentFromApps(String verifyId,String loginedUser,T_GW_APPS oldInfo,T_GW_APPS newInfo) {
        List<T_GW_CHANGES> changes = new ArrayList<>();
        //String c_CHANGE_TYPE,String c_CHANGE_FIELD,String c_CHANGE_VALUE,String c_VERIFY_ID
        T_GW_CHANGES change = null;
        if (!oldInfo.getC_APP_NAME().equals(newInfo.getC_APP_NAME())) {
            change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_APP_INFO,"c_APP_NAME",newInfo.getC_APP_NAME(),verifyId,loginedUser,0);
            changes.add(change);
        }
        if (!oldInfo.getC_APP_TYPE().equals(newInfo.getC_APP_TYPE())) {
            change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_APP_INFO,"c_APP_TYPE",newInfo.getC_APP_TYPE(),verifyId,loginedUser,0);
            changes.add(change);
        }
        if ((null != oldInfo.getC_APP_REMARK() && !oldInfo.getC_APP_REMARK().equals(newInfo.getC_APP_REMARK()))
                || (null == oldInfo.getC_APP_REMARK() && null != newInfo.getC_APP_REMARK()))
        {
            change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_APP_INFO,"c_APP_REMARK",newInfo.getC_APP_REMARK(),verifyId,loginedUser,0);
            changes.add(change);
        }
        return changes;
    }

    private List<T_GW_CHANGES> getDiffrentFromIps(String verifyId, String userId,List<T_GW_APP_IPS> ip1, List<T_GW_APP_IPS> ip2) {
        List<T_GW_CHANGES> changes = new ArrayList<>();
        //String c_CHANGE_TYPE,String c_CHANGE_FIELD,String c_CHANGE_VALUE,String c_VERIFY_ID
        T_GW_CHANGES change = null;
        if (CollectionUtils.isEmpty(ip1) && CollectionUtils.isEmpty(ip2)) {
            return changes;
        }
        if(CollectionUtils.isNotEmpty(ip1) && CollectionUtils.isNotEmpty(ip2) && ip1.containsAll(ip2) && ip2.containsAll(ip1)) {
            return changes;
        }
        int sizeOne = null == ip1 ? 0 : ip1.size();
        int sizeTwo = null == ip2 ? 0 : ip2.size();
        if (sizeTwo == 0) {
            for (T_GW_APP_IPS ip : ip1) {
                changes.add(new T_GW_CHANGES(SysConst.CHANGE_TYPE_APP_IP_DEL,"c_APP_IP",ip.getC_APP_IP(),verifyId,userId,null));
            }
        } else {
            int index = 0;
            for (T_GW_APP_IPS ip : ip2) {
                changes.add(new T_GW_CHANGES(SysConst.CHANGE_TYPE_APP_IP_ADD,"c_APP_IP",ip.getC_APP_IP(),verifyId,userId,index));
                changes.add(new T_GW_CHANGES(SysConst.CHANGE_TYPE_APP_IP_ADD,"c_APPIP_REMARK",ip.getC_APPIP_REMARK(),verifyId,userId,index));
                index ++;
            }
        }
        return changes;
    }

    @ResponseBody
    @RequestMapping(value = "/{c_APP_ID}/delete" , method = RequestMethod.POST)
    public MapUtils delete(@PathVariable(value = "c_APP_ID") String c_APP_ID) {
        return 1 == service.deleteApp(c_APP_ID) ? MapUtils.ok(): MapUtils.error("删除失败");
    }
    @ResponseBody
    @RequestMapping(value = "/{c_APP_ID}/verify" , method = RequestMethod.POST)
    @InvokeLog(name = "app register verify",description = "应用注册申请", logType = LogUtils.LOG_TYPE_OPERATE)
    public MapUtils verify(@PathVariable(value = "c_APP_ID") String c_APP_ID) {
        T_GW_APPS app = service.getById(c_APP_ID);
        if (app.getC_APP_STATUS().equals(SysConst.DICT_APP_STATUS_INIT)){
            service.updateAppStatus(app.getC_APP_ID(),SysConst.DICT_APP_STATUS_REG_UNAUDIT);
            return 1 == verifyService.insertVerify(((UserInfo)ShiroUtils.getSessionAttribute("user")).getUserId(),SysConst.VERIFY_TYPE_APP_REGISTER,c_APP_ID,null,null,null != app ? app.getC_APP_NAME(): "") ? MapUtils.ok(): MapUtils.error("提交注册申请失败");
        }
        return MapUtils.error("只有编辑状态可以提交注册申请!");
    }


    @ResponseBody
    @RequestMapping(value = "/{c_APP_ID}/offLine" , method = RequestMethod.POST)
    @InvokeLog(name = "app offline verify",description = "应用下线申请", logType = LogUtils.LOG_TYPE_OPERATE)
    public MapUtils offLine(@PathVariable(value = "c_APP_ID") String c_APP_ID,String c_VERIFY_REMARK) {
        T_GW_APPS app = service.getById(c_APP_ID);
        return 1 == verifyService.insertVerify(((UserInfo)ShiroUtils.getSessionAttribute("user")).getUserId(),SysConst.VERIFY_TYPE_APP_OFFLINE,c_APP_ID,null,c_VERIFY_REMARK,null != app ? app.getC_APP_NAME(): "") ? MapUtils.ok(): MapUtils.error("下线失败");
    }


    @ResponseBody
    @RequestMapping(value = "/{c_INTERFS_ID}/interfsOffLine" , method = RequestMethod.POST)
    @InvokeLog(name = "interfs offline verify",description = "接口下线申请", logType = LogUtils.LOG_TYPE_OPERATE)
    public MapUtils interfsOffLine(@PathVariable(value = "c_INTERFS_ID") String c_INTERFS_ID,String c_VERIFY_REMARK){
        T_GW_INTERFS interfs = interfService.get(c_INTERFS_ID);
        return 1 == verifyService.insertVerify(((UserInfo)ShiroUtils.getSessionAttribute("user")).getUserId(),SysConst.VERIFY_TYPE_INTERF_OFFLINE,interfs.getC_APP_ID(),c_INTERFS_ID,c_VERIFY_REMARK,null != interfs ? interfs.getC_INTERF_NAME(): "") ? MapUtils.ok(): MapUtils.error("下线失败");
    }


    @RequestMapping("/interfaces")
    public String enrollInterfs(Model model) {
        UserInfo userInfo = ShiroUtils.getUserInfo();
        model.addAttribute("appLists" , service.queryProviderList(userInfo.getCompanyId()));
        model.addAttribute("dataTypes" , dictService.queryForList(SysConst.DICT_GRP_IPARAMS_DATATYPE));
        return "enrolls/interfaces";
    }

    @ResponseBody
    @RequestMapping(value = "/interf-list")
    public List<T_GW_INTERFS> list(@RequestParam(value = "c_APP_ID" , required = false) String c_APP_ID ,
                                   @RequestParam(value = "c_INTERF_NAME", required = false) String c_INTERF_NAME) {
        UserInfo userInfo = ShiroUtils.getUserInfo();
        return interfService.queryForList(c_APP_ID,null,c_INTERF_NAME,userInfo.getCompanyId());
    }

    @ResponseBody
    @RequestMapping(value = "/interf/params")
    public List<T_GW_INTERF_PARAMS> iparamsList(@RequestParam(value = "c_INTERF_ID" , required = true) String c_INTERF_ID) {
        return interfService.queryInterfParams(c_INTERF_ID);
    }

    @ResponseBody
    @RequestMapping(value = "/interf/{saveType}")
    @InvokeLog(name = "save Interf" , description = "新增接口信息" , logType = LogUtils.LOG_TYPE_OPERATE)
    public MapUtils saveInterf(@PathVariable(value = "saveType") String saveType,@RequestBody String param) {
        GetInterfReq req = JSONObject.parseObject(param , GetInterfReq.class);
        req.setC_INTERF_STATUS(SysConst.DICT_INTERF_STATUS_INIT);
        if ("change".equals(saveType)) {
            return changeInterfs(req);
        } else {
            return interfService.saveInterfs(req, saveType);
        }
    }

    @ResponseBody
    @RequestMapping(value = "/testInterf" , method = RequestMethod.POST)
    public MapUtils testInterf(@RequestParam(value = "c_SOAP_MAIN" , required = true) String c_SOAP_MAIN,
                               @RequestParam(value = "c_END_POINT" , required = true) String c_END_POINT,
                               @RequestParam(value = "c_HTTP_METHOD" , required = true) String c_HTTP_METHOD,
                               @RequestParam(value = "c_OUT_PARAM_TYPE" , required = true) String c_OUT_PARAM_TYPE) {

        try {
            String rsp = WsSoapUtils.testWebservice(null,c_END_POINT,c_HTTP_METHOD,c_OUT_PARAM_TYPE,c_SOAP_MAIN.replaceAll("\\t",""));
            return MapUtils.ok().put("rsp" , rsp);
        } catch (Exception e) {
            e.printStackTrace();
            return MapUtils.error("测试连接失败");
        }
    }

    @ResponseBody
    @RequestMapping(value = "/interf/{c_INTERF_ID}/delete")
    @InvokeLog(name = "del Interf" , description = "删除接口信息" , logType = LogUtils.LOG_TYPE_OPERATE)
    public int delInterf(@PathVariable(value = "c_INTERF_ID") String c_INTERF_ID) {
        return interfService.deleteInterf(c_INTERF_ID);
    }

    @ResponseBody
    @RequestMapping(value = "/interf/{c_INTERF_ID}/reg")
    @InvokeLog(name = "reg Interf" , description = "接口注册申请" , logType = LogUtils.LOG_TYPE_OPERATE)
    public MapUtils regInterf(@PathVariable(value = "c_INTERF_ID") String c_INTERF_ID) {
        T_GW_INTERFS interf = interfService.get(c_INTERF_ID);
        if (interf.getC_INTERF_STATUS().equals(SysConst.DICT_INTERF_STATUS_INIT)){
            interfService.updateInterfStatus(interf.getC_INTERF_ID(),SysConst.DICT_INTERF_STATUS_UNAUDIT);
            return 1 == verifyService.insertVerify(((UserInfo)ShiroUtils.getSessionAttribute("user")).getUserId(),SysConst.VERIFY_TYPE_INTERF_REGISTER,interf.getC_APP_ID(),interf.getC_INTERF_ID(),null,null != interf ? interf.getC_INTERF_NAME(): "") ? MapUtils.ok("成功提交注册申请，请等待管理员审核"): MapUtils.error("提交注册申请失败");
        }
        return MapUtils.error("只有编辑状态可以提交注册申请!");
    }

    @Transactional
    @InvokeLog(name = "change interfaces" , description = "接口变更申请" , logType = LogUtils.LOG_TYPE_OPERATE)
    public MapUtils changeInterfs(GetInterfReq req ) {
        T_GW_INTERFS interf = interfService.get(req.getC_INTERF_ID());
        String verifyId = verifyService.getVerifyId();
        if (null != interf) {

            String userId= ShiroUtils.getUserInfo().getUserId();
            List<T_GW_CHANGES> changeList = getInterfChanges(verifyId,userId,interf,req);
            if (CollectionUtils.isNotEmpty(changeList)) {
                verifyService.updateVerifyToUnable(req.getC_APP_ID(),req.getC_INTERF_ID(),SysConst.VERIFY_TYPE_INTERF_CHANGED);
                if (1 ==verifyService.insertVerify(userId,verifyId,SysConst.VERIFY_TYPE_INTERF_CHANGED,req.getC_APP_ID(),req.getC_INTERF_ID(),null,req.getC_INTERF_NAME())) {
                    //batch insert to change
                    return 1 == changeService.batchInsert(changeList) ? MapUtils.ok("变更申请已提交!等待管理员审核!") : MapUtils.error("变更申请提交失败");
                }
                else {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                }
                return MapUtils.error("变更失败");

            } else {
                return MapUtils.ok("接口未做修改！");
            }

        } else {
            return MapUtils.error("请求信息不合法，请刷新页面后重试！");
        }
    }

    private List<T_GW_CHANGES> getInterfChanges (String verifyId,String loginUid,T_GW_INTERFS interf, GetInterfReq req) {
        T_GW_CHANGES change = new T_GW_CHANGES();
        List<T_GW_CHANGES> list = new ArrayList<>();
        if (!interf.getC_INTERF_NAME().equals(req.getC_INTERF_NAME())) {
            change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_INFO,"c_INTERF_NAME",req.getC_INTERF_NAME(),verifyId,loginUid,0);
            list.add(change);
        }
        if (!interf.getC_INTERF_METHOD_NAME().equals(req.getC_INTERF_METHOD_NAME())) {
            change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_INFO,"c_INTERF_METHOD_NAME",req.getC_INTERF_METHOD_NAME(),verifyId,loginUid,0);
            list.add(change);
        }
        if (
                (null == req.getC_INTERF_REMARK() && (null != interf.getC_INTERF_REMARK()))
                        || (null != req.getC_INTERF_REMARK() &&
                        (null == interf.getC_INTERF_REMARK()
                                || !req.getC_INTERF_REMARK().equals(interf.getC_INTERF_REMARK()))))
            if (null != req.getC_INTERF_REMARK()) {
                change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_INFO,"c_INTERF_REMARK",req.getC_INTERF_REMARK(),verifyId,loginUid,0);
                list.add(change);
            }

       /* if (!interf.getC_INTERF_SERVICE().equals(req.getC_INTERF_SERVICE())) {
            change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_SERVICE,"c_INTERF_SERVICE",req.getC_INTERF_SERVICE(),verifyId,loginUid,0);
            list.add(change);
        }*/
        if (!interf.getC_INTERF_ENDPOINT().equals(req.getC_INTERF_ENDPOINT())) {
            change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_SERVICE,"c_INTERF_ENDPOINT",req.getC_INTERF_ENDPOINT(),verifyId,loginUid,0);
            list.add(change);
        }
        if (!interf.getC_INTERF_NAMEP().equals(req.getC_INTERF_NAMEP())) {
            change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_SERVICE,"c_INTERF_NAMEP",req.getC_INTERF_NAMEP(),verifyId,loginUid,0);
            list.add(change);
        }
        if (!interf.getC_INTERF_METHOD_NAME().equals(req.getC_INTERF_METHOD_NAME())) {
            change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_SERVICE,"c_INTERF_METHOD_NAME",req.getC_INTERF_METHOD_NAME(),verifyId,loginUid,0);
            list.add(change);
        }

        if (!interf.getC_INTERF_UNIFY().equals(req.getC_INTERF_UNIFY())) {
            change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_INFO,"c_INTERF_UNIFY",req.getC_INTERF_UNIFY(),verifyId,loginUid,0);
            list.add(change);
            if ("1".equals(req.getC_INTERF_UNIFY())) {
                change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_INFO,"c_INTERF_SERVICE" , req.getC_INTERF_SERVICE(), verifyId,loginUid,0);
                list.add(change);
            } else {
                change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_INFO,"c_INTERF_SERVICE" , "", verifyId,loginUid,0);
                list.add(change);
            }
        }

        if (CollectionUtils.isNotEmpty(req.getIparams())) {
            List<T_GW_INTERF_PARAMS> iparams = interfService.queryInterfParams(req.getC_INTERF_ID());
            if(iparams.size() == req.getIparams().size() && iparams.containsAll(req.getIparams())) {
                return list;
            }
            int index = 0;
            for (T_GW_INTERF_PARAMS iprm : req.getIparams()) {
                change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_IPARAMS,"c_IPARAMS_ID" , iprm.getC_IPARAMS_ID(), verifyId,loginUid,index);
                list.add(change);

                change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_IPARAMS,"c_IPARAMS_NAME" , iprm.getC_IPARAMS_NAME(), verifyId,loginUid,index);
                list.add(change);

                change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_IPARAMS,"c_IPARAMS_REMARK" , iprm.getC_IPARAMS_REMARK(), verifyId,loginUid,index);
                list.add(change);

                change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_IPARAMS,"c_IPARAMS_SERVICE" , iprm.getC_IPARAMS_SERVICE(), verifyId,loginUid,index);
                list.add(change);

                change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_IPARAMS,"c_IPARAMS_DATATYPE" , iprm.getC_IPARAMS_DATATYPE(), verifyId,loginUid,index);
                list.add(change);


                change = new T_GW_CHANGES(SysConst.CHANGE_TYPE_INTERF_IPARAMS,"c_INTERF_ID" , req.getC_INTERF_ID(), verifyId,loginUid,index);
                list.add(change);

                index ++;
            }
        }
        return list;

    }
}
